/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	QMenu.java
 * 模块说明：	
 * 修改历史：
 * Dec 19, 2007 - lxm - 创建。
 */
package com.hd123.rumba.gwt.entry.client.menu;

import java.util.ArrayList;
import java.util.List;

import com.hd123.rumba.gwt.base.client.biz.BPersistent;
import com.hd123.rumba.gwt.base.client.exception.ClientBizException;

/**
 * 菜单 | 业务层.查询 | 实体
 * <p>
 * 
 * 适用于gwt模块MainFrame。
 * 
 * @author lxm
 * 
 */
public class QMenu extends BPersistent {

  public String getReaderClassName() throws ClientBizException {
    return "com.hd123.rumba.gwt.entry.server.menu.QMenuReader";
  }

  /** @gwt.typeArgs <com.hd123.rumba.gwt.entry.client.menu.QMenuItem> */
  private List items = new ArrayList();

  /**
   * 清除所有菜单项。
   * 
   * @throws ClientBizException
   */
  public void clear() throws ClientBizException {
    this.items.clear();
  }

  /**
   * 添加一个菜单项。
   * 
   * @param item
   *          指定被添加的菜单项。
   * @param parent
   *          指定所属上级菜单项。若传入null，表示添加的是顶级菜单项。
   * @throws ClientBizException
   */
  public void add(QMenuItem item, QMenuItem parent) throws ClientBizException {
    assert item != null;
    if (items.contains(item))
      return;
    item.setParent(parent);
    items.add(item);
  }

  /**
   * 取得第一个下级菜单项。
   * 
   * @param parent
   *          指定上级菜单项，允许null，表示取得顶级菜单项。
   * @return 返回菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getFirstChild(QMenuItem parent) throws ClientBizException {
    assert parent == null || items.contains(parent) : "指定的参数parent只能为空或者已被加入当前菜单。";
    QMenuItem retItem = null;
    int idx = 0;
    while (idx < items.size()) {
      QMenuItem item = (QMenuItem) items.get(idx);
      if ((parent == null && item.getParent() == null)
          || (parent != null && parent == item.getParent())) {
        retItem = item;
        break;
      }
      idx++;
    }
    return retItem;
  }

  /**
   * 取得最后一个下级菜单项。
   * 
   * @param parent
   *          指定上级菜单项，允许null，表示取得顶级菜单项。
   * @return 返回菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getLastChild(QMenuItem parent) throws ClientBizException {
    assert parent == null || items.contains(parent) : "指定的参数parent只能为空或者已被加入当前菜单。";
    QMenuItem retItem = null;
    int idx = items.size() - 1;
    while (idx >= 0) {
      QMenuItem item = (QMenuItem) items.get(idx);
      if ((parent == null && item.getParent() == null)
          || (parent != null && parent == item.getParent())) {
        retItem = item;
        break;
      }
      idx--;
    }
    return retItem;
  }

  /**
   * 取得相同上级菜单项的下一个菜单项。
   * 
   * @param item
   *          指定菜单项。
   * @return 返回菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getNextItem(QMenuItem item) throws ClientBizException {
    assert item != null && items.contains(item) : "指定的参数item不可为空或者已被加入当前菜单。";
    QMenuItem retItem = null;
    QMenuItem parent = item.getParent();
    int idx = items.indexOf(item) + 1;
    while (idx < items.size()) {
      QMenuItem item2 = (QMenuItem) items.get(idx);
      if ((parent == null && item2.getParent() == null)
          || (parent != null && parent == item2.getParent())) {
        retItem = item2;
        break;
      }
      idx++;
    }
    return retItem;
  }

  /**
   * 取得相同上级菜单项的上一个菜单项。
   * 
   * @param item
   *          指定菜单项。
   * @return 返回菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getPriorItem(QMenuItem item) throws ClientBizException {
    assert item != null && items.contains(item) : "指定的参数item不可为空或者已被加入当前菜单。";
    QMenuItem retItem = null;
    QMenuItem parent = item.getParent();
    int idx = items.indexOf(item) - 1;
    while (idx >= 0) {
      QMenuItem item2 = (QMenuItem) items.get(idx);
      if ((parent == null && item2.getParent() == null)
          || (parent != null && parent == item2.getParent())) {
        retItem = item2;
        break;
      }
      idx--;
    }
    return retItem;
  }

  /**
   * 按照顺序取得指定菜单项的所有直接子菜单项。
   * 
   * @param item
   *          指定的菜单项。允许传入null，表示取得所有顶级菜单项。
   * @return 返回符合条件的菜单项列表，若找不到则返回空的列表。
   * @throws ClientBizException
   */
  public List getDirectChildren(QMenuItem item) throws ClientBizException {
    assert item == null || items.contains(item) : "指定的参数item只能为空或者已被加入当前菜单。";
    List retList = new ArrayList();
    QMenuItem item2 = this.getFirstChild(item);
    while (item2 != null) {
      retList.add(item2);
      item2 = this.getNextItem(item2);
    }
    return retList;
  }

  /**
   * 根据标题取得菜单项。
   * 
   * @param parent
   *          指定被搜索菜单项的上级菜单项，若传入null，表示搜索顶级菜单项。
   * @param caption
   *          指定菜单项的标题。
   * @return 返回符合条件的菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getItemByCaption(QMenuItem parent, String caption) throws ClientBizException {
    assert parent == null || items.contains(parent) : "指定的参数parent只能为空或者已被加入当前菜单。";
    QMenuItem retItem = null;
    QMenuItem item = this.getFirstChild(parent);
    while (item != null) {
      if ((caption == null && item.getCaption() == null)
          || (caption != null && caption.equals(item.getCaption()))) {
        retItem = item;
        break;
      }
      item = this.getNextItem(item);
    }
    return retItem;
  }

  /**
   * 根据唯一标识查找菜单项。
   * 
   * @param id
   *          指定查找菜单项的唯一标识。
   * @return 返回找到的菜单项，若找不到则返回null。
   * @throws ClientBizException
   */
  public QMenuItem getItemById(String id) throws ClientBizException {
    assert id != null;
    QMenuItem retItem = null;
    for (int i = 0; i < items.size(); i++) {
      QMenuItem item = (QMenuItem) items.get(i);
      if (id.equals(item.getId())) {
        retItem = item;
        break;
      }
    }
    return retItem;
  }

  /**
   * 判断指定菜单项是否具有下级菜单项。
   * 
   * @param item
   *          指定菜单项。允许传入null，表示判断是否有顶级菜单项。
   * @return
   * @throws ClientBizException
   */
  public boolean hasChildren(QMenuItem item) throws ClientBizException {
    return this.getFirstChild(item) != null;
  }
}
